package com.plugin.manage.service.impl;

import com.plugin.core.model.entity.SysRole;
import com.plugin.core.model.entity.SysMenu;
import com.plugin.core.model.entity.SysPermission;
import com.plugin.manage.mapper.SysRoleMapper;
import com.plugin.manage.mapper.SysMenuMapper;
import com.plugin.manage.mapper.SysPermissionMapper;
import com.plugin.manage.service.ISysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统角色服务实现类
 * 
 * @author mark
 * @date 2025-07-28
 */
@Service
@Slf4j
public class SysRoleServiceImpl implements ISysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysPermissionMapper sysPermissionMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addRole(SysRole sysRole) {
        if (!StringUtils.hasText(sysRole.getRoleName())) {
            throw new RuntimeException("角色名称不能为空");
        }
        
        if (!StringUtils.hasText(sysRole.getRoleKey())) {
            throw new RuntimeException("角色标识不能为空");
        }

        // 检查角色名称是否已存在
        if (checkRoleNameExists(sysRole.getRoleName(), null)) {
            throw new RuntimeException("角色名称已存在");
        }

        // 检查角色标识是否已存在
        if (checkRoleKeyExists(sysRole.getRoleKey(), null)) {
            throw new RuntimeException("角色标识已存在");
        }

        // 设置默认值
        if (sysRole.getStatus() == null) {
            sysRole.setStatus("0"); // 默认正常状态
        }
        if (sysRole.getDel() == null) {
            sysRole.setDel("0"); // 默认未删除
        }

        int result = sysRoleMapper.insert(sysRole);
        if (result > 0) {
            log.info("新增角色成功，角色ID：{}", sysRole.getRoleId());
            return sysRole.getRoleId();
        } else {
            throw new RuntimeException("新增角色失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRole(Long roleId) {
        if (roleId == null) {
            throw new RuntimeException("角色ID不能为空");
        }

        // 软删除角色
        SysRole sysRole = new SysRole();
        sysRole.setRoleId(roleId);
        sysRole.setDel("1");

        int result = sysRoleMapper.updateById(sysRole);
        if (result > 0) {
            // 删除角色相关的权限
            sysPermissionMapper.deleteByRoleId(roleId);
            log.info("删除角色成功，角色ID：{}", roleId);
            return true;
        } else {
            throw new RuntimeException("删除角色失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchDeleteRole(List<Long> roleIds) {
        if (roleIds == null || roleIds.isEmpty()) {
            throw new RuntimeException("角色ID列表不能为空");
        }

        int successCount = 0;
        for (Long roleId : roleIds) {
            try {
                if (deleteRole(roleId)) {
                    successCount++;
                }
            } catch (Exception e) {
                log.error("删除角色失败，角色ID：{}", roleId, e);
            }
        }

        log.info("批量删除角色完成，成功删除{}个角色", successCount);
        return successCount;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRole(SysRole sysRole) {
        if (sysRole.getRoleId() == null) {
            throw new RuntimeException("角色ID不能为空");
        }

        if (StringUtils.hasText(sysRole.getRoleName())) {
            // 检查角色名称是否已存在（排除自己）
            if (checkRoleNameExists(sysRole.getRoleName(), sysRole.getRoleId())) {
                throw new RuntimeException("角色名称已存在");
            }
        }

        if (StringUtils.hasText(sysRole.getRoleKey())) {
            // 检查角色标识是否已存在（排除自己）
            if (checkRoleKeyExists(sysRole.getRoleKey(), sysRole.getRoleId())) {
                throw new RuntimeException("角色标识已存在");
            }
        }

        int result = sysRoleMapper.updateById(sysRole);
        if (result > 0) {
            log.info("更新角色成功，角色ID：{}", sysRole.getRoleId());
            return true;
        } else {
            throw new RuntimeException("更新角色失败");
        }
    }

    @Override
    public SysRole getRoleById(Long roleId) {
        if (roleId == null) {
            throw new RuntimeException("角色ID不能为空");
        }

        SysRole role = sysRoleMapper.selectByRoleId(roleId);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }

        return role;
    }

    @Override
    public SysRole getRoleByUserIdAndRoleId(Long userId, Long roleId) {
        if (userId == null || roleId == null) {
            throw new RuntimeException("用户ID和角色ID不能为空");
        }

        SysRole role = sysRoleMapper.selectByUserIdAndRoleId(userId, roleId);
        if (role == null) {
            throw new RuntimeException("角色不存在或用户无此角色权限");
        }

        return role;
    }

    @Override
    public List<SysRole> getRoleList(int offset, int limit, SysRole sysRole) {
        return sysRoleMapper.selectRoleList(offset, limit, sysRole);
    }

    @Override
    public List<SysRole> getAllRoles() {
        return sysRoleMapper.selectAllRoles();
    }

    @Override
    public Integer countRoles(SysRole sysRole) {
        return sysRoleMapper.countRoles(sysRole);
    }

    @Override
    public boolean checkRoleNameExists(String roleName, Long roleId) {
        if (!StringUtils.hasText(roleName)) {
            return false;
        }
        return sysRoleMapper.checkRoleNameExists(roleName, roleId) > 0;
    }

    @Override
    public boolean checkRoleKeyExists(String roleKey, Long roleId) {
        if (!StringUtils.hasText(roleKey)) {
            return false;
        }
        return sysRoleMapper.checkRoleKeyExists(roleKey, roleId) > 0;
    }

    @Override
    public List<SysMenu> getRolePermissions(Long roleId) {
        if (roleId == null) {
            throw new RuntimeException("角色ID不能为空");
        }

        return sysMenuMapper.selectMenusByRoleId(roleId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveRolePermissions(Long roleId, String menuIds) {
        if (roleId == null) {
            throw new RuntimeException("角色ID不能为空");
        }

        try {
            // 1. 删除角色原有的权限
            sysPermissionMapper.deleteByRoleId(roleId);

            // 2. 如果有新的权限，则添加
            if (StringUtils.hasText(menuIds)) {
                List<Long> menuIdList = Arrays.stream(menuIds.split(","))
                        .filter(StringUtils::hasText)
                        .map(String::trim)
                        .map(Long::valueOf)
                        .collect(Collectors.toList());

                if (!menuIdList.isEmpty()) {
                    List<SysPermission> permissions = new ArrayList<>();
                    for (Long menuId : menuIdList) {
                        SysPermission permission = new SysPermission();
                        permission.setRoleId(roleId);
                        permission.setResourceId(menuId);
                        permissions.add(permission);
                    }

                    // 批量插入权限
                    sysPermissionMapper.batchInsert(permissions);
                }
            }

            log.info("保存角色权限成功，角色ID：{}，菜单ID：{}", roleId, menuIds);
            return true;

        } catch (Exception e) {
            log.error("保存角色权限失败，角色ID：{}", roleId, e);
            throw new RuntimeException("保存角色权限失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchDeleteRoles(Long[] roleIds) {
        if (roleIds == null || roleIds.length == 0) {
            throw new RuntimeException("角色ID数组不能为空");
        }

        List<Long> roleIdList = Arrays.asList(roleIds);
        return batchDeleteRole(roleIdList);
    }

    @Override
    public List<SysRole> exportRoles(SysRole queryRole) {
        // 导出所有符合条件的角色，不分页
        return sysRoleMapper.selectRoleList(0, Integer.MAX_VALUE, queryRole);
    }

    @Override
    public List<SysRole> getRoleSelectList() {
        // 只返回正常状态的角色用于选择
        SysRole queryRole = new SysRole();
        queryRole.setStatus("0"); // 正常状态
        queryRole.setDel("0"); // 未删除
        return sysRoleMapper.selectRoleList(0, Integer.MAX_VALUE, queryRole);
    }
}
